#ifndef _RTC_TIME_H_
#define _RTC_TIME_H_

#include "stdint.h"
#include "time.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define RTC_SEC_PER_MIN 60L
#define RTC_MIN_PER_HOUR 60L
#define RTC_HOUR_PER_DAY 24L
#define RTC_MIN_PER_DAY (RTC_MIN_PER_HOUR * RTC_HOUR_PER_DAY)
#define RTC_SEC_PER_DAY (RTC_SEC_PER_MIN * RTC_MIN_PER_DAY)

    extern const uint8_t srtc_mon_day_p[12];
    extern const uint8_t srtc_mon_day_r[12];
    extern const uint16_t srtc_day_in_year_p[12];
    extern const uint16_t srtc_day_in_year_r[12];

    typedef struct
    {
        uint8_t sec;   
        uint8_t min;   
        uint8_t hour;  
        uint8_t week;  
        uint8_t day;   
        uint8_t mon;   
        uint16_t year; 
    } TIME_Type;

    typedef union
    {
        uint32_t val;
        struct
        {
            uint32_t sec2t : 5;
            uint32_t min : 6;
            uint32_t hour : 5;
            uint32_t day : 5;
            uint32_t mon : 4;
            uint32_t year : 7;
        } time;
    } sig_time_type;

    typedef union
    {
        uint32_t val;
        struct
        {
            uint32_t min : 7;
            uint32_t hour : 6;
            uint32_t day : 6;
            uint32_t mon : 5;
            uint32_t year : 8;
        } time;
    } bcd_time_type;

    typedef union
    {
        uint16_t val;
        struct
        {
            uint16_t day : 5;
            uint16_t mon : 4;
            uint16_t year : 7;
        } time;
    } ymd_time_type;

    void TimeRun(TIME_Type *TimeCur);
    void rtc_time_run_sec(TIME_Type *TimeCur, uint32_t sec_add);
    void rtc_time_run_min(TIME_Type *TimeCur, uint32_t min_add);
    void rtc_time_run_hour(TIME_Type *TimeCur, uint32_t hour_add);

    int8_t TimeCompare(TIME_Type *pTime1, TIME_Type *pTime2);
    void TimeCopy(TIME_Type *pTimeSrc, TIME_Type *pTimeDes);

    bcd_time_type time_sig_to_bcd(sig_time_type sig_time);
    sig_time_type time_bcd_to_sig(bcd_time_type bcd_time);
    bcd_time_type time_to_bcd(TIME_Type *time);
    sig_time_type time_to_sig(TIME_Type *pTimeSrc);
    void time_sig_to_time(sig_time_type sig, TIME_Type *pTimeSrc);

    int8_t AsciiToTime(uint8_t *Src, TIME_Type *pTime);
    uint8_t TimeToAscii(TIME_Type *pTime, uint8_t *Des);
    uint8_t TimeNoSecToAscii(TIME_Type *pTime, uint8_t *Des);
    uint8_t DateToAscii(TIME_Type *pTime, uint8_t *Des);
    uint8_t ClockTimeToAscii(TIME_Type *pTime, uint8_t *Des);
    uint8_t bcd_time_to_ascii(bcd_time_type bcd_time, uint8_t *des);

    uint16_t sig_to_ascii(sig_time_type sig, uint8_t *buff);
    uint16_t sig_sec_to_ascii(sig_time_type sig, uint8_t *buff);
    uint16_t sig_date_to_ascii(sig_time_type sig, uint8_t *buff);
    uint16_t sig_time_to_ascii(sig_time_type sig, uint8_t *buff);
    uint16_t sig_time_sec_to_ascii(sig_time_type sig, uint8_t *buff);

    void rtc_year_base_set(int16_t year);
    int16_t rtc_year_base_get(void);

    time_t sig_time_diff(sig_time_type start, sig_time_type end);
    uint8_t sig_time_to_tm(sig_time_type sig, struct tm *tim);
    uint8_t time_to_tm(TIME_Type *time, struct tm *tim);

    int32_t sig_time_to_min(sig_time_type sig);
    
    int32_t sig_time_min_diff(sig_time_type sig1, sig_time_type sig2);
    
    int32_t sig_time_sec_diff(sig_time_type sig1, sig_time_type sig2);
    
    int32_t sig_time_sec2t_diff(sig_time_type sig1, sig_time_type sig2);

    int32_t rtc_time_to_min(TIME_Type *rtc);
    
    int32_t rtc_time_min_diff(TIME_Type *rtc1, TIME_Type *rtc2);

    int32_t rtc_time_sec_diff(TIME_Type *rtc1, TIME_Type *rtc2);

    int32_t ymd_time_to_day(ymd_time_type sig);
    int32_t ymd_time_day_diff(ymd_time_type ydm1, ymd_time_type ydm2);
    ymd_time_type sig_time_to_ymd(sig_time_type sig);
    sig_time_type ymd_time_to_sig(ymd_time_type ymd);

#ifdef __cplusplus
}
#endif

#endif 
